home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / ImageMagick / combine.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  24KB  |  691 lines

  1. /*
  2. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3. %                                                                             %
  4. %                                                                             %
  5. %                                                                             %
  6. %                CCCC   OOO   M   M  BBBB   IIIII  N   N  EEEEE               %
  7. %               C      O   O  MM MM  B   B    I    NN  N  E                   %
  8. %               C      O   O  M M M  BBBB     I    N N N  EEE                 %
  9. %               C      O   O  M   M  B   B    I    N  NN  E                   %
  10. %                CCCC   OOO   M   N  BBBB   IIIII  N   N  EEEEE               %
  11. %                                                                             %
  12. %                                                                             %
  13. %                        Digitally combine two images.                        %
  14. %                                                                             %
  15. %                                                                             %
  16. %                                                                             %
  17. %                              Software Design                                %
  18. %                                John Cristy                                  %
  19. %                               January 1993                                  %
  20. %                                                                             %
  21. %                                                                             %
  22. %  Copyright 1994 E. I. Dupont de Nemours & Company                           %
  23. %                                                                             %
  24. %  Permission to use, copy, modify, distribute, and sell this software and    %
  25. %  its documentation for any purpose is hereby granted without fee,           %
  26. %  provided that the above Copyright notice appear in all copies and that     %
  27. %  both that Copyright notice and this permission notice appear in            %
  28. %  supporting documentation, and that the name of E. I. Dupont de Nemours     %
  29. %  & Company not be used in advertising or publicity pertaining to            %
  30. %  distribution of the software without specific, written prior               %
  31. %  permission.  E. I. Dupont de Nemours & Company makes no representations    %
  32. %  about the suitability of this software for any purpose.  It is provided    %
  33. %  "as is" without express or implied warranty.                               %
  34. %                                                                             %
  35. %  E. I. Dupont de Nemours & Company disclaims all warranties with regard     %
  36. %  to this software, including all implied warranties of merchantability      %
  37. %  and fitness, in no event shall E. I. Dupont de Nemours & Company be        %
  38. %  liable for any special, indirect or consequential damages or any           %
  39. %  damages whatsoever resulting from loss of use, data or profits, whether    %
  40. %  in an action of contract, negligence or other tortuous action, arising     %
  41. %  out of or in connection with the use or performance of this software.      %
  42. %                                                                             %
  43. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  44. %
  45. %  The combine program syntax is:
  46. %
  47. %  Usage: combine [options ...] input_file1 input_file2 output_file
  48. %
  49. %  Where options include:
  50. %    -alpha              store alpha channel if the image has one
  51. %    -colors value       preferred number of colors in the image
  52. %    -compose operator   composite operator
  53. %    -colorspace type    GRAY, OHTA, RGB, XYZ, YCbCr, YIQ, or YUV
  54. %    -comment string     annotate image with comment
  55. %    -compress type      RunlengthEncoded or QEncoded
  56. %    -density geometry   vertical and horizontal density of the image
  57. %    -display server     obtain image or font from this X server
  58. %    -dither             apply Floyd/Steinberg error diffusion to image
  59. %    -font name          X11 font for displaying text
  60. %    -geometry geometry  width and height of the image
  61. %    -interlace type     NONE, LINE, or PLANE
  62. %    -label name         assign a label to an image
  63. %    -monochrome         transform image to black and white
  64. %    -page geometry      size and location of the Postscript page
  65. %    -quality value      JPEG quality setting
  66. %    -scene value        image scene number
  67. %    -stereo             combine two images to form red-green stereo image
  68. %    -treedepth value    depth of the color classification tree
  69. %    -verbose            print detailed information about the image
  70. %
  71. %  Change '-' to '+' in any option above to reverse its effect.  For
  72. %  example,  specify +alpha to store the image without its alpha channel.
  73. %
  74. %
  75. */
  76.  
  77. #include "magick.h"
  78. #include "image.h"
  79. #include "X.h"
  80.  
  81. /*
  82. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  83. %                                                                             %
  84. %                                                                             %
  85. %                                                                             %
  86. %   U s a g e                                                                 %
  87. %                                                                             %
  88. %                                                                             %
  89. %                                                                             %
  90. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  91. %
  92. %  Procedure Usage displays the program usage;
  93. %
  94. %  The format of the Usage routine is:
  95. %
  96. %      Usage()
  97. %
  98. %
  99. */
  100. static void Usage()
  101. {
  102.   char
  103.     **p;
  104.  
  105.   static char
  106.     *options[]=
  107.     {
  108.       "-alpha              store alpha channel if the image has one",
  109.       "-colors value       preferred number of colors in the image",
  110.       "-colorspace type    GRAY, OHTA, RGB, XYZ, YCbCr, YIQ, or YUV",
  111.       "-comment string     annotate image with comment",
  112.       "-compose operator   composite operator",
  113.       "-compress type      RunlengthEncoded or QEncoded",
  114.       "-density geometry   vertical and horizontal density of the image",
  115.       "-display server     obtain image or font from this X server",
  116.       "-dither             apply Floyd/Steinberg error diffusion to image",
  117.       "-font name          X11 font for displaying text",
  118.       "-geometry geometry  width and height of the image",
  119.       "-interlace type     NONE, LINE, or PLANE",
  120.       "-label name         assign a label to an image",
  121.       "-monochrome         transform image to black and white",
  122.       "-page geometry      size and location of the Postscript page",
  123.       "-quality value      JPEG quality setting",
  124.       "-scene value        image scene number",
  125.       "-stereo             combine two images to form red-green stereo image",
  126.       "-treedepth value    depth of the color classification tree",
  127.       "-verbose            print detailed information about the image",
  128.       (char *) NULL
  129.     };
  130.   (void) fprintf(stderr,
  131.     "Usage: %s [options ...] input_file1 input_file2 output_file\n",
  132.     client_name);
  133.   (void) fprintf(stderr,"\nWhere options include:\n");
  134.   for (p=options; *p != (char *) NULL; p++)
  135.     (void) fprintf(stderr,"  %s\n",*p);
  136.   (void) fprintf(stderr,
  137.     "\nChange '-' to '+' in any option above to reverse its effect.  For\n");
  138.   (void) fprintf(stderr,
  139.     "example,  specify +alpha to store the image without an alpha channel.\n");
  140.   exit(1);
  141. }
  142.  
  143. /*
  144. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  145. %                                                                             %
  146. %                                                                             %
  147. %                                                                             %
  148. %  M a i n                                                                    %
  149. %                                                                             %
  150. %                                                                             %
  151. %                                                                             %
  152. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  153. %
  154. %
  155. */
  156. int main(argc,argv)
  157. int
  158.   argc;
  159.  
  160. char
  161.   *argv[];
  162. {
  163. #define NotInitialized  (unsigned int) (~0)
  164.  
  165.   char
  166.     *comment,
  167.     *density,
  168.     *filename,
  169.     *font,
  170.     *image_geometry,
  171.     *label,
  172.     *option,
  173.     *page_geometry,
  174.     *server_name;
  175.  
  176.   double
  177.     normalized_maximum_error,
  178.     normalized_mean_error;
  179.  
  180.   Image
  181.     *alpha_image,
  182.     *beta_image,
  183.     *combined_image;
  184.  
  185.   ImageInfo
  186.     image_info;
  187.  
  188.   int
  189.     i,
  190.     status,
  191.     x;
  192.  
  193.   time_t
  194.     start_time;
  195.  
  196.   unsigned int
  197.     alpha,
  198.     colorspace,
  199.     compose,
  200.     compression,
  201.     dither,
  202.     interlace,
  203.     mean_error_per_pixel,
  204.     monochrome,
  205.     number_colors,
  206.     quality,
  207.     scene,
  208.     stereo,
  209.     tree_depth,
  210.     verbose;
  211.  
  212.   unsigned long
  213.     total_colors;
  214.  
  215.   /*
  216.     Initialize program variables.
  217.   */
  218.   client_name=argv[0];
  219.   if (argc < 4)
  220.     Usage();
  221.   /*
  222.     Read image and convert to MIFF format.
  223.   */
  224.   alpha=NotInitialized;
  225.   alpha_image=(Image *) NULL;
  226.   beta_image=(Image *) NULL;
  227.   colorspace=RGBColorspace;
  228.   comment=(char *) NULL;
  229.   compose=OverCompositeOp;
  230.   compression=UndefinedCompression;
  231.   density=(char *) NULL;
  232.   dither=False;
  233.   font=(char *) NULL;
  234.   image_geometry=(char *) NULL;
  235.   interlace=NoneInterlace;
  236.   label=(char *) NULL;
  237.   monochrome=False;
  238.   number_colors=0;
  239.   page_geometry=(char *) NULL;
  240.   quality=85;
  241.   scene=0;
  242.   server_name=(char *) NULL;
  243.   start_time=time((time_t *) NULL);
  244.   stereo=False;
  245.   tree_depth=0;
  246.   verbose=False;
  247.   /*
  248.     Check command syntax.
  249.   */
  250.   filename=(char *) NULL;
  251.   for (i=1; i < (argc-1); i++)
  252.   {
  253.     option=argv[i];
  254.     if (((int) strlen(option) < 2) || ((*option != '-') && (*option != '+')))
  255.       {
  256.         /*
  257.           Read input images.
  258.         */
  259.         filename=argv[i];
  260.         GetImageInfo(filename,&image_info);
  261.         image_info.server_name=server_name;
  262.         image_info.font=font;
  263.         image_info.geometry=image_geometry;
  264.         image_info.page=page_geometry;
  265.         image_info.density=density;
  266.         image_info.interlace=interlace;
  267.         image_info.quality=quality;
  268.         image_info.verbose=verbose;
  269.         if (alpha_image == (Image *) NULL)
  270.           {
  271.             alpha_image=ReadImage(&image_info);
  272.             if (alpha_image == (Image *) NULL)
  273.               exit(1);
  274.             continue;
  275.           }
  276.         if (beta_image != (Image *) NULL)
  277.           Error("input images already specified",filename);
  278.         beta_image=ReadImage(&image_info);
  279.         if (beta_image == (Image *) NULL)
  280.           exit(1);
  281.       }
  282.     else
  283.       switch(*(option+1))
  284.       {
  285.         case 'a':
  286.         {
  287.           alpha=(*option == '-');
  288.           break;
  289.         }
  290.         case 'c':
  291.         {
  292.           if (strncmp("colors",option+1,7) == 0)
  293.             {
  294.               number_colors=0;
  295.               if (*option == '-')
  296.                 {
  297.                   i++;
  298.                   if ((i == argc) || !sscanf(argv[i],"%d",&x))
  299.                     Error("Missing colors on -colors",(char *) NULL);
  300.                   number_colors=atoi(argv[i]);
  301.                 }
  302.               break;
  303.             }
  304.           if (strncmp("colorspace",option+1,7) == 0)
  305.             {
  306.               colorspace=RGBColorspace;
  307.               if (*option == '-')
  308.                 {
  309.                   i++;
  310.                   if (i == argc)
  311.                     Error("Missing type on -colorspace",(char *) NULL);
  312.                   option=argv[i];
  313.                   colorspace=UndefinedColorspace;
  314.                   if (Latin1Compare("gray",option) == 0)
  315.                     {
  316.                       colorspace=GRAYColorspace;
  317.                       number_colors=256;
  318.                       tree_depth=8;
  319.                     }
  320.                   if (Latin1Compare("ohta",option) == 0)
  321.                     colorspace=OHTAColorspace;
  322.                   if (Latin1Compare("rgb",option) == 0)
  323.                     colorspace=RGBColorspace;
  324.                   if (Latin1Compare("xyz",option) == 0)
  325.                     colorspace=XYZColorspace;
  326.                   if (Latin1Compare("ycbcr",option) == 0)
  327.                     colorspace=YCbCrColorspace;
  328.                   if (Latin1Compare("yiq",option) == 0)
  329.                     colorspace=YIQColorspace;
  330.                   if (Latin1Compare("yuv",option) == 0)
  331.                     colorspace=YUVColorspace;
  332.                   if (colorspace == UndefinedColorspace)
  333.                     Error("Invalid colorspace type on -colorspace",option);
  334.                 }
  335.               break;
  336.             }
  337.           if (strncmp("comment",option+1,4) == 0)
  338.             {
  339.               comment=(char *) NULL;
  340.               if (*option == '-')
  341.                 {
  342.                   i++;
  343.                   if (i == argc)
  344.                     Error("Missing comment on -comment",(char *) NULL);
  345.                   comment=argv[i];
  346.                 }
  347.               break;
  348.             }
  349.           if (strncmp("compose",option+1,5) == 0)
  350.             {
  351.               compose=ReplaceCompositeOp;
  352.               if (*option == '-')
  353.                 {
  354.                   i++;
  355.                   if (i == argc)
  356.                     Error("Missing type on -compose",(char *) NULL);
  357.                   option=argv[i];
  358.                   compose=UndefinedCompositeOp;
  359.                   if (Latin1Compare("over",option) == 0)
  360.                     compose=OverCompositeOp;
  361.                   if (Latin1Compare("in",option) == 0)
  362.                     compose=InCompositeOp;
  363.                   if (Latin1Compare("out",option) == 0)
  364.                     compose=OutCompositeOp;
  365.                   if (Latin1Compare("atop",option) == 0)
  366.                     compose=AtopCompositeOp;
  367.                   if (Latin1Compare("xor",option) == 0)
  368.                     compose=XorCompositeOp;
  369.                   if (Latin1Compare("plus",option) == 0)
  370.                     compose=PlusCompositeOp;
  371.                   if (Latin1Compare("minus",option) == 0)
  372.                     compose=MinusCompositeOp;
  373.                   if (Latin1Compare("add",option) == 0)
  374.                     compose=AddCompositeOp;
  375.                   if (Latin1Compare("subtract",option) == 0)
  376.                     compose=SubtractCompositeOp;
  377.                   if (Latin1Compare("difference",option) == 0)
  378.                     compose=DifferenceCompositeOp;
  379.                   if (Latin1Compare("replace",option) == 0)
  380.                     compose=ReplaceCompositeOp;
  381.                   if (compose == UndefinedCompositeOp)
  382.                     Error("Invalid compose type on -compose",option);
  383.                 }
  384.               break;
  385.             }
  386.           if (strncmp("compress",option+1,3) == 0)
  387.             {
  388.               compression=NoCompression;
  389.               if (*option == '-')
  390.                 {
  391.                   i++;
  392.                   if (i == argc)
  393.                     Error("Missing type on -compress",(char *) NULL);
  394.                   option=argv[i];
  395.                   if (Latin1Compare("runlengthencoded",option) == 0)
  396.                     compression=RunlengthEncodedCompression;
  397.                   else
  398.                     if (Latin1Compare("qencoded",option) == 0)
  399.                       compression=QEncodedCompression;
  400.                     else
  401.                       Error("Invalid compression type on -compress",option);
  402.                 }
  403.               break;
  404.             }
  405.           Error("Unrecognized option",option);
  406.           break;
  407.         }
  408.         case 'd':
  409.         {
  410.           if (strncmp("density",option+1,3) == 0)
  411.             {
  412.               density=(char *) NULL;
  413.               if (*option == '-')
  414.                 {
  415.                   i++;
  416.                   if ((i == argc) || !sscanf(argv[i],"%d",&x))
  417.                     Error("Missing geometry on -density",(char *) NULL);
  418.                   density=argv[i];
  419.                 }
  420.               break;
  421.             }
  422.           if (strncmp("display",option+1,3) == 0)
  423.             {
  424.               server_name=(char *) NULL;
  425.               if (*option == '-')
  426.                 {
  427.                   i++;
  428.                   if (i == argc)
  429.                     Error("Missing server name on -display",(char *) NULL);
  430.                   server_name=argv[i];
  431.                 }
  432.               break;
  433.             }
  434.           if (strncmp("dither",option+1,3) == 0)
  435.             {
  436.               dither=(*option == '-');
  437.               break;
  438.             }
  439.           Error("Unrecognized option",option);
  440.           break;
  441.         }
  442.         case 'f':
  443.         {
  444.           font=(char *) NULL;
  445.           if (*option == '-')
  446.             {
  447.               i++;
  448.               if (i == argc)
  449.                 Error("Missing font name on -font",(char *) NULL);
  450.               font=argv[i];
  451.             }
  452.           break;
  453.         }
  454.         case 'g':
  455.         {
  456.           image_geometry=(char *) NULL;
  457.           if (*option == '-')
  458.             {
  459.               i++;
  460.               if ((i == argc) || !sscanf(argv[i],"%d",&x))
  461.                 Error("Missing geometry on -geometry",(char *) NULL);
  462.               image_geometry=argv[i];
  463.             }
  464.           break;
  465.         }
  466.         case 'h':
  467.         {
  468.           Usage();
  469.           break;
  470.         }
  471.         case 'i':
  472.         {
  473.           if (strncmp("interlace",option+1,3) == 0)
  474.             {
  475.               interlace=NoneInterlace;
  476.               if (*option == '-')
  477.                 {
  478.                   i++;
  479.                   if (i == argc)
  480.                     Error("Missing type on -interlace",(char *) NULL);
  481.                   option=argv[i];
  482.                   interlace=UndefinedInterlace;
  483.                   if (Latin1Compare("none",option) == 0)
  484.                     interlace=NoneInterlace;
  485.                   if (Latin1Compare("line",option) == 0)
  486.                     interlace=LineInterlace;
  487.                   if (Latin1Compare("plane",option) == 0)
  488.                     interlace=PlaneInterlace;
  489.                   if (interlace == UndefinedInterlace)
  490.                     Error("Invalid interlace type on -interlace",option);
  491.                 }
  492.               break;
  493.             }
  494.           Error("Unrecognized option",option);
  495.           break;
  496.         }
  497.         case 'm':
  498.         {
  499.           if (strncmp("monochrome",option+1,2) == 0)
  500.             {
  501.               monochrome=(*option == '-');
  502.               if (monochrome)
  503.                 {
  504.                   number_colors=2;
  505.                   tree_depth=8;
  506.                   colorspace=GRAYColorspace;
  507.                 }
  508.               break;
  509.             }
  510.           Error("Unrecognized option",option);
  511.           break;
  512.         }
  513.         case 'l':
  514.         {
  515.           if (strncmp("label",option+1,2) == 0)
  516.             {
  517.               label=(char *) NULL;
  518.               if (*option == '-')
  519.                 {
  520.                   i++;
  521.                   if (i == argc)
  522.                     Error("Missing label name on -label",(char *) NULL);
  523.                   label=argv[i];
  524.                 }
  525.               break;
  526.             }
  527.           Error("Unrecognized option",option);
  528.           break;
  529.         }
  530.         case 'p':
  531.         {
  532.           if (strncmp("page",option+1,2) == 0)
  533.             {
  534.               page_geometry=(char *) NULL;
  535.               if (*option == '-')
  536.                 {
  537.                   i++;
  538.                   if ((i == argc) || !sscanf(argv[i],"%d",&x))
  539.                     Error("Missing page geometry on -page",(char *) NULL);
  540.                   page_geometry=argv[i];
  541.                 }
  542.               break;
  543.             }
  544.           Error("Unrecognized option",option);
  545.           break;
  546.         }
  547.         case 'q':
  548.         {
  549.           i++;
  550.           if ((i == argc) || !sscanf(argv[i],"%d",&x))
  551.             Error("Missing quality on -quality",(char *) NULL);
  552.           quality=atoi(argv[i]);
  553.           break;
  554.         }
  555.         case 's':
  556.         {
  557.           if (strncmp("scene",option+1,2) == 0)
  558.             {
  559.               scene=0;
  560.               if (*option == '-')
  561.                 {
  562.                   i++;
  563.                   if ((i == argc) || !sscanf(argv[i],"%d",&x))
  564.                     Error("Missing scene number on -scene",(char *) NULL);
  565.                   scene=atoi(argv[i]);
  566.                 }
  567.               break;
  568.             }
  569.           if (strncmp("stereo",option+1,2) == 0)
  570.             {
  571.               stereo=(*option == '-');
  572.               break;
  573.             }
  574.           Error("Unrecognized option",option);
  575.           break;
  576.         }
  577.         case 't':
  578.         {
  579.           tree_depth=0;
  580.           if (*option == '-')
  581.             {
  582.               i++;
  583.               if ((i == argc) || !sscanf(argv[i],"%d",&x))
  584.                 Error("Missing depth on -treedepth",(char *) NULL);
  585.               tree_depth=atoi(argv[i]);
  586.             }
  587.           break;
  588.         }
  589.         case 'v':
  590.         {
  591.           verbose=(*option == '-');
  592.           break;
  593.         }
  594.         default:
  595.         {
  596.           Error("Unrecognized option",option);
  597.           break;
  598.         }
  599.       }
  600.   }
  601.   if ((alpha_image == (Image *) NULL) || (beta_image == (Image *) NULL))
  602.     Usage();
  603.   /*
  604.     Combine image.
  605.   */
  606.   if (stereo)
  607.     combined_image=StereoImage(alpha_image,beta_image);
  608.   else
  609.     {
  610.       int
  611.         x_offset,
  612.         y_offset;
  613.  
  614.       unsigned int
  615.         size;
  616.  
  617.       /*
  618.         Digitally composite image.
  619.       */
  620.       x_offset=0;
  621.       y_offset=0;
  622.       if (image_info.geometry != (char *) NULL)
  623.         (void) XParseGeometry(image_info.geometry,&x_offset,&y_offset,&size,
  624.           &size);
  625.       CompositeImage(beta_image,compose,alpha_image,x_offset,y_offset);
  626.       combined_image=beta_image;
  627.     }
  628.   if (combined_image == (Image *) NULL)
  629.     exit(1);
  630.   /*
  631.     Write image.
  632.   */
  633.   total_colors=0;
  634.   if (alpha != NotInitialized)
  635.     combined_image->alpha=alpha;
  636.   if (compression != UndefinedCompression)
  637.     combined_image->compression=compression;
  638.   if (scene != 0)
  639.     combined_image->scene=scene;
  640.   (void) strcpy(combined_image->filename,argv[i]);
  641.   LabelImage(combined_image,label);
  642.   if (comment != (char *) NULL)
  643.     CommentImage(combined_image,comment);
  644.   if (number_colors != 0)
  645.     {
  646.       /*
  647.         Reduce the number of colors in the image.
  648.       */
  649.       if ((combined_image->class == DirectClass) ||
  650.           (combined_image->colors > number_colors) ||
  651.           (colorspace == GRAYColorspace))
  652.         QuantizeImage(combined_image,number_colors,tree_depth,dither,colorspace,
  653.           True);
  654.       if (verbose)
  655.         {
  656.           /*
  657.             Measure quantization error.
  658.            */
  659.            QuantizationError(combined_image,&mean_error_per_pixel,
  660.              &normalized_mean_error,&normalized_maximum_error);
  661.            total_colors=NumberColors(combined_image,(FILE *) NULL);
  662.         }
  663.       SyncImage(combined_image);
  664.     }
  665.   status=WriteImage(&image_info,combined_image);
  666.   if (verbose)
  667.     {
  668.       /*
  669.         Display detailed info about the image.
  670.       */
  671.       (void) fprintf(stderr,"[%u] %s %s=>%s %ux%u",combined_image->scene,
  672.         alpha_image->filename,filename,combined_image->filename,
  673.         combined_image->columns,combined_image->rows);
  674.       if (combined_image->class == DirectClass)
  675.         (void) fprintf(stderr," DirectClass");
  676.       else
  677.         if (total_colors == 0)
  678.           (void) fprintf(stderr," PseudoClass %uc",combined_image->colors);
  679.         else
  680.           {
  681.             (void) fprintf(stderr," PseudoClass %lu=>%uc",total_colors,
  682.               combined_image->colors);
  683.             (void) fprintf(stderr," %u/%.6f/%.6fe",mean_error_per_pixel,
  684.               normalized_mean_error,normalized_maximum_error);
  685.           }
  686.       (void) fprintf(stderr," %s %lds\n",combined_image->magick,
  687.         time((time_t *) NULL)-start_time+1);
  688.     }
  689.   return(!status);
  690. }
  691.